#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "StdUdp.h"

struct StdUdpServer
{
    int sock;
    char ip[20];
    short port;
};



UdpS *InitUdpServer(const char *ip, short port)
{
    UdpS *s=(UdpS*)malloc(sizeof(UdpS));
    if(s==NULL)
    {
        printf("initudpserver malloc error\n");
        return NULL;
    }
    s->sock=socket(AF_INET,SOCK_DGRAM,0);
    if(s->sock<0)
    {
        perror("udp sock");
        free(s);
        return NULL;
    }
    s->port=port;
    strcpy(s->ip,ip);
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(s->port);
    addr.sin_addr.s_addr=inet_addr(s->ip);
    if(bind(s->sock,(struct sockaddr*)&addr,sizeof(addr))<0)
    {
        perror("udp bind");
        free(s);
        return NULL;
    }
    return s;

}

void UdpServerSend(UdpS *s, char *destip, const short destport, void *ptr, size_t size)
{
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(destport);
    addr.sin_addr.s_addr=inet_addr(destip);
    if(sendto(s->sock,ptr,size,0,(struct sockaddr*)&addr,sizeof(addr))<0)
    {
        perror("udpserversend to");
    }
}

void UdpServerReceive(UdpS *s,void *ptr, size_t size)
{
    struct sockaddr_in clinetaddr;
    socklen_t len;
    char temp[100]={0};
    if(recvfrom(s->sock,ptr,100,0,(struct sockaddr*)&clinetaddr,&len)<=0)
    {
        perror("UdpServerReceive");
    }

}

void CloseServer(UdpS *s)
{
    close(s->sock);
    free(s);
}

struct StdUdpClinet
{
    int sock;
    char ip[20];
    short port;
};

UdpC *InitUdpClinet(const char *serverip, const short port)
{
    UdpC *c=(UdpC *)malloc(sizeof(UdpC));
    if(c==NULL)
    {
        printf("InitUdpClinet malloc error\n");
        return NULL;
    }
    c->sock=socket(AF_INET,SOCK_DGRAM,0);
    if(c->sock<0)
    {
        perror("InitUdpClinet sock");
        free(c);
        return NULL;
    }
    strcpy(c->ip,serverip);
    c->port=port;
    return c;
}


void UdpClinetSend(UdpC *c, void *ptr, size_t size)
{
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(c->port);
    addr.sin_addr.s_addr=inet_addr(c->ip);
    if(sendto(c->sock,ptr,size,0,(struct sockaddr*)&addr,sizeof(addr))<0)
    {
        perror("UdpClinetSend to");
    }
}


void CloseClinet(UdpC *c)
{
    close(c->sock);
    free(c);
}
